/****************************************************************************
**  Tite Interactive Text Engine (TiTE)
**  Copyright (C) 2010  Eisoft Group
**
**  This file is part of TiTE.
**
**  TiTE is free software: you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation, either version 3 of the License, or
**  (at your option) any later version.
**
**  TiTE is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with TiTE.  If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/

/*!
 * \file optimization_nullptr.hpp
 *
 * \date 01/10/2011
 */

#ifndef TITE_OPTIMIZATION_NULLPTR_HPP
#define TITE_OPTIMIZATION_NULLPTR_HPP

/**
 * Not an optimization, but improves type-safey and prevents incorrect usage
 * of NULL if nullptr is available.
 *
 * If nullptr is not implemented by the compiler, then a workaround is used,
 * which can be found here: <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf>.
 */
#if (_MSC_VER < 1600) || (defined(__GNUC__) && (((__GNUC__ * 100) + (__GNUC_MINOR__ * 10) + __GNUC_PATCHLEVEL__) < 460))
    // This is a const object...
    const class 
    {
    public:
        // convertible to any type of null non-member pointer...
        template<typename T>
        operator T*(void) const 
        {
            return 0;
        }

        // or any type of null member pointer...
        template<typename T, typename U>
        operator U T::*(void) const
        {
            return 0;
        }

    private:
        // whose address cannot be taken...
        void operator&(void) const;
    } nullptr = {}; // and whose name is nullptr.
#else
    // Do nothing, we already have nullptr!
#endif /* nullptr definition */

#endif /* TITE_OPTIMIZATION_NULLPTR_HPP */